﻿#pragma once

#include <vector>
#include <opencv2/imgproc.hpp>
#include <opencv2/line_descriptor.hpp>
#include "../ImageShow/CImageShow.h"

class CV_EXPORT LineMatch
{
public:
	LineMatch(void);
	~LineMatch(void);

	int MatchImage( );
	int MatchImage1( );
	int MatchImage3( cv::String, cv::Point2f &_MarkCentor, cv::Mat _IsShow = cv::Mat() );
	int MatchImage3( cv::Point2f &_MarkCentor, cv::Mat _IsShow = cv::Mat() );
	bool SetTemplate( std::string &_templatePath, cv::Mat _isShow = cv::Mat() );
	bool SetTemplate( cv::Mat &templateMat,  cv::Mat _isShow = cv::Mat() );
	//bool SetImage(CMvImage &_mvImage );
	bool SetImage(cv::Mat &_Image );

	//获得Mark的12个顶点
	bool GetMarkCorner( cv::Mat &, std::vector <cv::Point> &, cv::Point2f &_centor, cv::Mat _imgOut = cv::Mat(), int _epsilon = 7 );

	//获得顶点线段长度
	void CornerToLen( std::vector<cv::Point> &,  std::vector<double> &);

	//将输入的线段分到长短边中去，仅靠长度来判断
	void ClassifyLine( std::vector <cv::line_descriptor::KeyLine> &_lineIn, 
		std::vector < std::vector <cv::line_descriptor::KeyLine> > &_KeyLine, 
		double shortSide, double lenghtSide, double _epsilon = 0.08 );

	void ClassifyTempLine( std::vector <cv::line_descriptor::KeyLine> &_lineIn, 
		std::vector <std::vector <cv::line_descriptor::KeyLine>> &_tmpLine,
		double shortSide, double lenghtSide, double _epsilon = 0.08 );

	//根据两条相交的边，推算出Mark的中心来
	bool CalMarkCentor( std::vector < std::vector <cv::line_descriptor::KeyLine> > &_KeyLine, cv::Point2f &_Centor, 
		std::vector <std::vector <cv::line_descriptor::KeyLine>> &_tmpLine, cv::Point2f &_tmpCentor, cv::Mat _show = cv::Mat() );

	bool IsLineCorner( cv::line_descriptor::KeyLine &_Line1,cv::line_descriptor::KeyLine &_Line2, float _distance, float _angle );
	float PointDistance( cv::Point2f &_p1, cv::Point2f &_p2 );

	float Point2LineDistance( cv::Point2f &_p, cv::line_descriptor::KeyLine &_Line);
	float disPa2Linebc1(double xa,double ya,double xb,double yb,double xc,double yc);
	int GetCrossePoint( cv::Point2f &_Line1_p1, cv::Point2f &_Line1_p2, cv::Point2f &_Line2_p1, cv::Point2f &_Line2_p2, cv::Point2f &_c );
	bool GetCrossLine( std::vector < std::vector <cv::line_descriptor::KeyLine> > &_KeyLines, int _vec_ind0, int _vec_ind1, int &_ind0, int &_ind1, 
		cv::Point2f *_crossLinePoint,cv::Point2f &_tmpCentor, std::vector <std::vector <cv::line_descriptor::KeyLine>> &_tmpLine );

	void (*Log_Add_wstring)(std::wstring, int level );
	void (*Log_Add_string)(std::string, int level );

	void Log_Add(std::wstring, int level=0 );
	void Log_Add(std::string, int level=0 );

public:
	enum 
	{
		//组成十字mark的12条边
		//第一种方法只考虑横竖长短，分成四组
		SHORT_LINE_H = 0,
		SHORT_LINE_V,
		LENGHT_LINE_H, 
		LENGHT_LINE_V,
		KEYLINE_4_SIZES,

		//第二种方法按照线段的角度，分成八组
		LENGHT_LINE_V_1_5 = 0,
		LENGHT_LINE_H_2_10,
		LENGHT_LINE_H_4_8,
		LENGHT_LINE_V_7_11,
		SHORT_LINE_V_3,
		SHORT_LINE_H_6,
		SHORT_LINE_V_9,
		SHORT_LINE_H_12,
		KEYLINE_8_SIZES
	};
	std::vector < std::vector <cv::line_descriptor::KeyLine> > ImageKeyLine;
	cv::Point2f m_TemplateCentor;
	double m_TemplateShort, m_TemplateLenght;
	std::vector <std::vector <cv::line_descriptor::KeyLine>> m_TemplateLines;
	cv::Mat m_ImageIn;
	float m_Distance; 
	float m_AngleRemainder;
};
